import functools
import json
import random
import string
import time
import requests

from app import db
from application.tools.comm import sendMsg
from captcha.image import ImageCaptcha
from flask import Blueprint, request, send_file, jsonify, redirect
from application.models.users.user import *
from application.tools.myjwt import mjwt
from application.tools.myredis import r

course_blue = Blueprint("courseblue", __name__)
# 添加课程使用， 获取标签， 分类， 类别
@course_blue.route("/getTags")
def getTags():
    tags = Tags.query.all()
    tagslist = [{"id": i.id,"name": i.name}for i in tags]
    types = Ctype.query.all()
    typeslist = [{"id": i.id, "name": i.name}for i in types]
    ctype = CourseType.query.all()
    ctypelist = [{"id": i.id, "name": i.name}for i in ctype]
    return jsonify({"code": 200, "tags": tagslist, "types": typeslist, "clist": ctypelist})

# 七牛云
@course_blue.route("/get_qntoken")
def get_qntoken():
    # -*- coding: utf-8 -*-
    # flake8: noqa
    from qiniu import Auth
    # 需要填写你的 Access Key 和 Secret Key
    access_key = 'PreRDw06bAO6l1rp3jYQ14emYXPu4YAz-kXxc7Im'
    secret_key = 'ImiyB_v7CH-QJgnc5cNbjRMCjx_mvm_dAtwEO0OM'
    # 构建鉴权对象
    q = Auth(access_key, secret_key)
    # 要上传的空间
    bucket_name = 'h2205a-ljy'
    # 3600为token过期时间，秒为单位。3600等于一小时
    token = q.upload_token(bucket_name)
    return jsonify({"code": 200, "token": token})
# 添加课程
@course_blue.route('/addCourse', methods=['POST'])
def addCourse():
    try:
        # 获取参数
        data = json.loads(request.data)
        # 校验参数是否获取
        if not data:
            return jsonify({"code": 400, "msg": "缺少参数"})
        # 写入课程表
        course = Course(name=data.get('name'), url=data.get('url'), descrip=data.get('desc'), ctype=data.get("type"))
        db.session.add(course)
        # 获取新加的课程id
        scourse = Course.query.filter(Course.name == data['name']).first()

        # 写入课程标签
        for i in data['tags']:
            tag = Tags.query.filter(Tags.id==i).first()
            scourse.tags.append(tag)
            # sql = "insert into course_tag(courseid,tagid) values(%d,%d)"%(scourse.id, int(i))
            # db.session.execute(sql)

        # 课程分类表
        for i in data['ctype']:
            sql = "insert into course_cate(courseid,course_typeid) values(%d,%d)"%(scourse.id, int(i))
            db.session.execute(sql)
        db.session.commit()
        return jsonify({"code": 200, "msg": "添加成功"})
    except:
        db.session.rollback()
        return jsonify({"code": 400, "msg": "添加失败"})

import math
# @user_blue.route("/getCourse")
# def getCourse():
#     # 获取参数page
#     page = request.args.get("page")
#     # 获取已上线， 即将上线条件
#     online = int(request.args.get('is_publish'))
#     # 查询总条数
#     total = Course.query.filter(Course.is_publish == online).count()
#     # 定义每页显示多少条
#     page_size = 3
#     # 查询当前页记录
#     start = math.ceil((int(page)-1)*page_size)
#     # 获取排序字段
#     orderpara = request.args.get('orderpara')
#     print("orderpata=====", orderpara)
#     if orderpara == "new":
#         course = Course.query.order_by(Course.create_time.desc()).filter(Course.is_publish == online).offset(start).limit(page_size).all()
#     else:
#         course = Course.query.order_by(Course.views.desc()).filter(Course.is_publish == online).offset(start).limit(page_size).all()
#
#     # 获取过来的数据必须序列化
#     list = [{"id": i.id, "name": i.name, "url": i.url, "views": i.views} for i in course]
#     # 返回结果
#     return jsonify({"code": 200, "clist": list, "total": total, "page_size": page_size})




# # flask期末作业
# @user_blue.route("/student")
# def student():
#     # 获取参数page
#     page = request.args.get("page")
#     # 查询总条数
#     total = Student.query.count()
#     # 定义每页显示多少条
#     page_size = 2
#     # 查询当前页记录
#     start = math.ceil((int(page)-1)*page_size)
#     # 分页获取的数据
#     student = Student.query.offset(start).limit(page_size).all()
#     # 获取过来的数据必须序列化
#     list = [{"id": i.id, "name": i.name, "number": i.number} for i in student]
#     # 返回结果
#     return jsonify({"code": 200, "clist": list, "total": total, "page_size": page_size})

@course_blue.route('/getCourse', methods=['GET'])
def getCourse():
    # 获取当前页面
    page = request.args.get("page")
    # 获取已上线， 即将上线条件
    online = int(request.args.get('is_publish'))

    # 定义每页显示多少条
    page_size = 3
    # 获取条件
    start = math.ceil((int(page)-1)*page_size)
    # 获取类别
    types = int(request.args.get('types'))
    # 获取类别
    tags = int(request.args.get('tags'))
    # 排序字段
    orderpara = request.args.get('orderpara')
    # 重构where条件
    where = " 1=1"
    if online:
        where = where + " and c.is_publish="+str(online)

    if types > 0:
        where = where + " and c.ctype="+str(types)

    # 排序
    orderby = " order by c.views desc"
    if orderpara == "new":
        orderby = " order by c.create_time desc"
    # 查询一共有多少条
    if tags > 0:
        countsql = "select count(c.id) as tcount from course as c inner join course_tag as ct on c.id=ct.courseid where ct.tagid=" + str(tags)+" and"+where
    else:
        countsql = "select count(c.id) as tcount from course as c where"+where
    cres = db.session.execute(countsql)
    cdata = cres.fetchone()
    # 查询总条数
    total = cdata["tcount"]
    # 查询当前页对象
    if tags > 0:
        sql = "select c.* from course as c inner join course_tag as ct on c.id=ct.courseid where ct.tagid=" + str(tags) + " and " + where + orderby + " limit " + str(start) + "," + str(page_size)
    else:
        sql = "select c.* from course as c where " + where+orderby+" limit "+str(start)+","+str(page_size)
    res = db.session.execute(sql)
    data = res.fetchall()
    # 获取过来的数据必须序列化
    clist = [{"id": i.id, "name": i.name, "url": i.url, "views": i.views} for i in data]
    # 返回结果
    return jsonify({"code": 200, "clist": clist, "total": total, "page_size": page_size})

# 课程详情页面
@course_blue.route('/courseDetail', methods=['GET'])
def courseDetail():
    # 获取参数id
    course_id = request.args.get("cid")
    userid = request.args.get("userid")
    # 查询课程
    # sql = "SELECT * from course WHERE id="+str(course_id)
    # data = db.session.execute(sql)
    # cou = data.fetchall()
    cou = Course.query.filter(Course.id == course_id).first()
    coudict = {"id": cou.id, "name": cou.name, "views": cou.views, "descrip": cou.descrip, "tcount": cou.tcount, "son": [], "ctype": cou.ctype}

    # 判断用户是否登录
    if userid:
        key = "user" + str(userid) + "good" + str(course_id)
        r.hash_add(key, "id", cou.id)
        r.hash_add(key, "name", "商品"+str(cou.name))
        r.hash_add(key, "url", cou.url)

    # 通过课程id查询课程
    sql = "SELECT * FROM jie  where courseid=%s order by tcount asc" % course_id
    res = db.session.execute(sql)
    course = res.fetchall()
    # 课程章节列表
    list = []
    for i in course:
        dict = {"id": i.id, "name": i.name, "tcount": i.tcount, "url": i.url}
        list.append(dict)
    coudict["son"] = list

    return jsonify({"code": 200, "cou": coudict})


# 浏览记录
@course_blue.route('/getDetail', methods=['GET'])
def getDetail():
    # 接收参数
    userid = request.args.get('userid')
    findkey = "user" + str(userid) + "*"
    gidlist = r.getvalues(findkey)
    reslist = []
    for i in gidlist:
        goods = r.getall_hash(i)
        dict = {}
        for k, v in goods.items():
            kk = k.decode()
            vv = v.decode()
            dict[kk] = vv
        reslist.append(dict)
    return jsonify({"code": 200, "reslist": reslist})


# 加入购物车
@course_blue.route('/buy', methods=['GET'])
def buy():
    # 获取参数 userid  course
    userid = request.args.get('userid')
    course_id = request.args.get('course_id')
    # 加减类型
    type = 1
    try:
        type = request.args.get('type')
    except:
        pass
    # 从hash中获取数据 如果存在+1 buy1course
    key = "buy"+str(userid)+"course"+str(course_id)
    # 如果不存在存入redis hash
    flag = r.findkey_hash(key)
    if flag:
        # 数据+1
        ff = r.jiajian_hash(key, "number", 1, type)
        if ff == False:
            return jsonify({"code": 10010, "mes": "不能在减了"})
    else:
        r.hash_add(key, "id", course_id)
        r.hash_add(key, "number", 1)
        # 默认为选中
        r.hash_add(key, "flag", "True")
    return jsonify({"code": 200})

# 获取购物车
@course_blue.route('/mycart', methods=['GET'])
def mycart():
    # 获取参数 userid
    userid = request.args.get('userid')
    # 从hash中获取商品id
    key = 'buy' + str(userid) + "*"
    goods = r.getvalues(key)
    glist = []
    tmoney = 0
    tcount = 0
    if goods:
        for i in goods:
            # 获取每一条商品的具体信息
            good = r.getall_hash(i)
            rescourse={}
            for k, v in good.items():
                params = k.decode()
                values = v.decode()

                if params == "id":
                    # 获取到数据库商品信息
                    tcourse = Tcourse.query.filter(Tcourse.id == values).first()
                    rescourse["id"] = tcourse.id
                    rescourse["name"] = tcourse.title
                    rescourse["url"] = tcourse.url
                    rescourse["price"] = tcourse.price
                if params == "number":
                    # 获取到数据库商品数量
                    rescourse['number'] = values
                if params == "flag":
                    if values == "True":
                        rescourse['flag'] = True
                    else:
                        rescourse["flag"] = False


            rescourse['total'] = int(rescourse['price']) * int(rescourse['number'])
            # 计算总价格
            if rescourse['flag'] == True:
                tmoney = float(tmoney) + float(rescourse['total'])
                tcount = int(tcount) + int(rescourse['number'])
            glist.append(rescourse)
    # 价格，图片，名字。。。。。从mysql中获取， 从redsi商品缓存中读取
    # 数据重组返回
    return jsonify({"code": 200, "glist": glist, "tmoney": tmoney, "tcount": tcount})

# 获取训练营课程
@course_blue.route("/bootcamp")
def bootcamp():
    # 获取数据库存储的所有训练营课程
    trourse = Tcourse.query.all()
    clist = []
    # 序列化返回
    for i in trourse:
        clist.append({
            "id": i.id,
            "name": i.title,
            "url": i.url,
            "price": i.price,
            "store": i.store,
            "intro": i.intro
        })
    # 返回数据
    return jsonify({"code": 200, "clist": clist})

# 修改单个选中
@course_blue.route('/modifyStatus', methods=['GET'])
def modifyStatus():
    # 接收参数 userid  goodsid
    userid = request.args.get('userid')
    cid = request.args.get('cid')
    # 获取过来的判断状态
    key = "buy"+str(userid)+"course"+str(cid)
    flag = r.getone_hash(key, "flag")
    # 设置默认为选中
    cflag = "True"
    # 如果true改为false，如果false改为true
    if flag:
        flag = flag.decode()
        # 根据返回结果选中相反的
        if flag == "True":
            cflag = "False"

        r.hash_add(key, "flag", cflag)
        return jsonify({"code": 200})

@course_blue.route("/modifyAllStatus")
def modifyAllStatus():
    userid = request.args.get('userid')
    status = request.args.get('status')
    flag = "false"
    if status == "true":
        flag = "True"
    # 把购物车全部修改为选中或者未选中
    keys = r.getvalues("buy"+str(userid)+"*")
    for i in keys:
        r.hash_add(i,'flag', flag)
    return jsonify({"code": 200})

# 生成订单
@course_blue.route('/create_order', methods=['POST'])
def create_order():
    # 接收参数 userid
    data = json.loads(request.data)
    userid = data.get("userid")
    # 接口幂等性操作， 验证
    order_token = data["order_token"]
    value = r.str_get(order_token)
    if not value:
        return jsonify({"code":10010, "mes": "已经生成不能重复操作"})
    # 删除
    r.str_del(order_token)
    # 根据userid查询购物车
    key = "buy" + str(data['userid']) + "*"
    glist = r.getvalues(key)
    totalmoney = 0
    # 生成订单号
    order_on = str(random.randint(10,99))+str(data['userid'])
    # 判断购物车中已经选中的记录
    if glist:
        # 写入订单表
        order = Orders(order_no=int(order_on), userid=userid)
        db.session.add(order)
        for i in glist:
            flag = r.getone_hash(i, 'flag')
            # 获取每一条商品的具体信息
            if flag:
                flag = flag.decode()
                # 根据返回结果
                if flag == "True":
                    # id 商品id
                    id = r.getone_hash(i,'id')
                    id = id.decode()
                    # 商品数量
                    number = r.getone_hash(i, 'number')
                    number = number.decode()
                    # 判断购物车中已经选中的记录
                    tcourse = Tcourse.query.filter(Tcourse.id == id).first()
                    # 查询训练营课程表, 判断库存
                    if int(tcourse.store) < int(number):
                        return jsonify({"code": 10010, "mes": "库存不足"})
                    # 写入订单详情表
                    tmoney = float(tcourse.price) * float(number)
                    detil = OrdersDetall(order_no=int(order_on), courseid=id, number=number, price=tcourse.price, tmoney=tmoney)
                    db.session.add(detil)
                    # 总价
                    totalmoney = float(totalmoney) + float(tmoney)
                    # 删除购物车已经选中的记录
                    r.str_del(i)

        order.tmoney = totalmoney
        db.session.add(order)
        db.session.commit()
        return jsonify({"code": 200, "orderno": order_on})

# 订单表展示
@course_blue.route("/orders")
def orders():
    # 获取参数 userid
    # order_no = request.args.get('order_no')
    # # 查询订单表
    # order = Orders.query.filter(Orders.order_no == orderno).all()
    # olist = [{
    #     "id": i.id,
    #     "orderno": i.order_no,
    #     "userid": i.userid,
    #     "tmoney": i.tmoney,
    #     "status": i.status,
    # }
    #     for i in order]
    # # 查询订单详情表
    # orderdetall = OrdersDetall.query.filter(OrdersDetall.order_no == orderno).all()
    # clist = [{
    #     "id": i.id,
    #     "orderno": i.order_no,
    #     "courseid": i.courseid,
    #     "number": i.number,
    #     "price": i.price,
    #     "tmoney": i.tmoney,
    # } for i in orderdetall]
    # # 序列化返回
    # 接收参数
    order_no = request.args.get('order_no')
    # sql = "select o.order_no,o.tmoney,od.order_no,od.courseid,od.cname, od.price from orders as o inner join orders_detail as od on o.order_no=od.order_no;"
    # res = db.session.execute(sql)
    # data = res.fetchall()
    # print(data)
    # orderdice = []
    # idlist = []
    # for i in data:
    #     if i[0] not in idlist:
    #         dict={"id": i[0],"tmoney": i[1], "details": []}
    #         orderdice.append(dict)
    #         idlist.append(i[0])
    #
    # # 遍历list
    # for (index, j) in enumerate(orderdice):
    # # 遍历data
    #     for i in data:
    #         print("index----------------j", index, j)
    #         # 判断data 中的父类订单号和list中订单号是否相同
    #         if i[2] == j["id"]:
    #             j['details'].append(
    #                 {
    #                     "order_on": i[2],
    #                     "courseid": i[3],
    #                     "cname": i[4],
    #                     "price": i[5],
    #                 }
    #             )
    #             print(j[index])
                # j[index]['details'].append({
                #     "order_on": i[2],
                #     "courseid": i[3],
                #     "cname": i[4],
                #     "price": i[5],
                # })
    orderdice = {}
    orders = Orders.query.filter(Orders.order_no == order_no).first()
    if orders:
        orderdice["order_no"] = orders.order_no
        orderdice["tmoney"] = orders.tmoney
        list = []
        for i in orders.details:
            list.append({
                "courseid":i.courseid,
                "cname": i.cname,
                "price": i.price,
                "number": i.number,
                "tmoney": i.tmoney,
            })
        orderdice["details"] = list

    return jsonify({"code": 200, "orderdice": orderdice})






# 接口幂等性操作
import uuid
@course_blue.route("get_order_token")
def get_order_token():
    # 生成token
    token = uuid.uuid1().hex
    # 将token存入redisf
    r.str_add(token, "1")
    # 返回结果
    return jsonify({"token": token, "code": 200})
from application.tools.comm import get_ali_object
# 订单表支付
@course_blue.route("/pay_order", methods=['GET'])
def pay_order():
    # 获取参数
    order_no = request.args.get('order_no')
    # 通过订单号查询价格
    order = Orders.query.filter(Orders.order_no == order_no).first()
    # 支付， 返回支付url
    # 生成支付的url
    pay = get_ali_object()

    # 订单号重构充值1 支付订单2
    orders = str(order_no)+':'+str(2)
    query_params = pay.direct_pay(
        subject="test",  # 商品简单描述
        out_trade_no=str(orders),  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=float(order.tmoney),  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({"code": 200, "url": pay_url})

# 课程章节选择课程添加
@course_blue.route("/get_course", methods=['GET'])
def add_chapter():
    # 获取全部课程
    course = Course.query.all()
    # 课程章节列表
    list = []
    for i in course:
        dict = {"id": i.id, "name": i.name}
        list.append(dict)
    return jsonify({"code": 200, "list": list})

import os
# 保存图片到本地
@course_blue.route("/upload", methods=["POST"])
def upload():
    # 获取文件
    file = request.files.get('file')
    # 获取文件名
    filename = file.filename
    path = os.path.join("upload/media/"+filename)
    # 保存文件
    file.save(path)
    # 通过id获取到数据， url
    # 用url接收数据库中的url
    # remove加上数据库中的url就可以直接删除
    # 删除文件
    # os.remove(url)

    return jsonify({"code": 200, "url": path})

# 添加课程章节杰克
@course_blue.route("/addjie", methods=["POST"])
def addjie():
    # 获取参数
    data = json.loads(request.data)
    if not data:
        return jsonify({"code": 10010, "mes": "参数错误"})
    # 添加课程章节
    name = data['name']
    url = data['url']
    tcount = data['tcount']
    courseid = data['courseid']
    try:
        jie = Jie(name=name, url=url, tcount=tcount, courseid=courseid)
        db.session.add(jie)
        db.session.commit()
    except Exception as e:
        print(e)
        return jsonify({"code": 10010, "mes": "章节添加失败"})
    return jsonify({"code": 200, "mes": "章节添加成功"})

# # 老师的信息
# @course_blue.route("/teacher_info", methods=["GET"])
# def teacher_info():
#     # 获取参数
#     course_id = request.args.get("course_id")
#     # 查询课程表
#     sql = "SELECT * from teacher where"
#     list = []
#     print("-----------------------------", tcharts)
#     return jsonify({"code": 200})